"""
https://leetcode.cn/problems/binary-tree-preorder-traversal/description/

144. 二叉树的前序遍历
简单
相关标签
相关企业
给你二叉树的根节点 root ，返回它节点值的 前序 遍历。

 

示例 1：

输入：root = [1,null,2,3]

输出：[1,2,3]

解释：



示例 2：

输入：root = [1,2,3,4,5,null,8,null,null,6,7,9]

输出：[1,2,4,5,6,7,3,8,9]

解释：



示例 3：

输入：root = []

输出：[]

示例 4：

输入：root = [1]

输出：[1]

 

提示：

树中节点数目在范围 [0, 100] 内
-100 <= Node.val <= 100
 

进阶：递归算法很简单，你可以通过迭代算法完成吗？

"""

# Definition for a binary tree node.
from typing import List, Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    """
    利用左序遍历，遍历顺序是中左右的特点，恰好可以使用队列实现
    即：作为父节点的“中”，仅当在遍历的最前面的顺序时，才可利用队列的特性。
    另一种可行的顺序，是 中 右 左。但这个顺序并不属于任何官方默认的顺序

    不妨考虑下，为什么中序遍历（左 中 右），或者后序遍历（左 右 中）能否使用队列直接实现？
    而只有父节点先拿出来遍历，才能紧接着拿到左右子树。如果不消费（使用结果队列接收），就必须先放到一个位置，而考虑到到一个节点同时可以是父子，很难处理。

    如果是后序遍历，可以考虑从后向前追加结果，按照 中 右 左的顺序。

    另一个注意的点是，使用缓存列表时，并不是从缓存中去拿最前面的节点，反而是去拿最后面的节点（左子树）。
    这样可以保证中间的顺序是左子树。

    """

    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if not root:
            return []
        # 中 左 右
        res:List[int]=[]
        
        node_stack:List[TreeNode]=[root]
        
        while node_stack:
            temp=node_stack.pop()
            res.append(temp.val)
            
            if temp.right:
                node_stack.append(temp.right)
            if temp.left:
                node_stack.append(temp.left)

        return res
        

if __name__=='__main__':
    solution = Solution()

    node1 = TreeNode(1,TreeNode(2),TreeNode(3))
    res=solution.preorderTraversal(node1)
    print(res)

    pass